package cn.example.demo.modules.house.service.impl;

import cn.example.demo.modules.house.dto.MealsDto;
import cn.example.demo.modules.house.entity.Meals;
import cn.example.demo.modules.house.mapper.MealsMapper;
import cn.example.demo.modules.house.service.IMealsService;
import cn.example.demo.common.model.service.ServiceResult;
import cn.example.demo.common.retrieval.PageBean;
import cn.example.demo.common.secure.annotation.DataScopeEnable;
import cn.example.demo.common.secure.context.LoginUserApi;
import cn.example.demo.common.tools.QueryServiceUtils;
import cn.example.demo.common.tools.obj.reflect.EntityUtils;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 描述：【餐饮】接口实现类
 */
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Service
public class MealsServiceImpl extends ServiceImpl<MealsMapper, Meals> implements IMealsService {
    @Autowired
    private LoginUserApi loginUserApi;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult insertMeals(MealsDto mealsDto) {
        Meals entity = EntityUtils.entityConvert(mealsDto, new Meals(), false);

        entity.setMealStatus(1);

        if (this.save(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【餐饮，ID:{}】创建成功!", entity.getId()), entity);
        }

        return ServiceResult.isInternalError("【餐饮】创建失败，未知错误！");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult updateMeals(MealsDto mealsDto) {
        Meals entity = this.getById(mealsDto.getId());
        if (entity == null) {
            return ServiceResult.isNotFound(StrUtil.format("【餐饮】信息更新失败：记录不存在！ID:{}", mealsDto.getId()));
        }

        entity = EntityUtils.entityConvert(mealsDto, entity, true);
        if (this.updateById(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【餐饮，ID:{}】信息更新成功!", entity.getId()), null);
        }

        return ServiceResult.isNotModified("未知错误，【餐饮】信息修改失败！");
    }

    @Override
    public PageBean queryMeals(MealsDto mealsDto) {
        // 当前实现类代理对象
        MealsServiceImpl proxy = (MealsServiceImpl) AopContext.currentProxy();

        Page pageResult = PageHelper.startPage(mealsDto.getPageNum(), mealsDto.getPageSize())
                .doSelectPage(() -> this.list(getQueryWrapper(mealsDto)));

        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteMeals(MealsDto mealsDto) {
        int rows = this.baseMapper.deleteBatchIds(mealsDto.getIds());
        if (rows > 0) {
            return ServiceResult.isSuccess(StrUtil.format("操作成功，已批量删除【餐饮】共 {} 条记录！", rows), rows);
        }

        return ServiceResult.isNotModified("删除【餐饮】失败，请稍后重试！");
    }

    @Override
    public Meals findMealsById(String id) {
        return this.getById(id);
    }

    @Override
    public List<Map<String, Object>> queryMealsAsDict(MealsDto mealsDto) {
        return this.baseMapper.selectAsDictList(getQueryWrapper(mealsDto));
    }

    /**
     * 查询条件
     *
     * @param mealsDto
     * @return
     */
    @DataScopeEnable
    protected LambdaQueryWrapper getQueryWrapper(MealsDto mealsDto) {
        LambdaQueryWrapper<Meals> wrapper = Wrappers.lambdaQuery();

        wrapper
            .eq(StrUtil.isNotBlank(mealsDto.getId()), Meals::getId, mealsDto.getId())

            .like(StrUtil.isNotBlank(mealsDto.getTitle()), Meals::getTitle, mealsDto.getTitle())

            .like(StrUtil.isNotBlank(mealsDto.getMealImageUrl()), Meals::getMealImageUrl, mealsDto.getMealImageUrl())

            .eq(mealsDto.getPrice() != null, Meals::getPrice, mealsDto.getPrice())
    
            .eq(mealsDto.getCount() != null, Meals::getCount, mealsDto.getCount())
    
            .like(StrUtil.isNotBlank(mealsDto.getMaterial()), Meals::getMaterial, mealsDto.getMaterial())

            .like(StrUtil.isNotBlank(mealsDto.getSource()), Meals::getSource, mealsDto.getSource())

            .like(StrUtil.isNotBlank(mealsDto.getAdmissionImageUrl()), Meals::getAdmissionImageUrl, mealsDto.getAdmissionImageUrl())

            .eq(mealsDto.getMealStatus() != null, Meals::getMealStatus, mealsDto.getMealStatus())
    
            .eq(mealsDto.getOrganizationId() != null, Meals::getOrganizationId, mealsDto.getOrganizationId())
    
            .eq(mealsDto.getCreateUser() != null, Meals::getCreateUser, mealsDto.getCreateUser())
    
            .like(StrUtil.isNotBlank(mealsDto.getCreateUserName()), Meals::getCreateUserName, mealsDto.getCreateUserName())

            .ge(mealsDto.getCreateTimeStart() != null, Meals::getCreateTime, mealsDto.getCreateTimeStart())
            .le(mealsDto.getCreateTimeEnd() != null, Meals::getCreateTime, mealsDto.getCreateTimeEnd())

            .eq(mealsDto.getUpdateUser() != null, Meals::getUpdateUser, mealsDto.getUpdateUser())
    
            .like(StrUtil.isNotBlank(mealsDto.getUpdateUserName()), Meals::getUpdateUserName, mealsDto.getUpdateUserName())

            .ge(mealsDto.getUpdateTimeStart() != null, Meals::getUpdateTime, mealsDto.getUpdateTimeStart())
            .le(mealsDto.getUpdateTimeEnd() != null, Meals::getUpdateTime, mealsDto.getUpdateTimeEnd())
;

        return wrapper;
    }
}
